package com.springboot2.infrastructure.websocket;

import com.alibaba.fastjson.JSONObject;
import com.springboot2.infrastructure.entity.SocketData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.*;

import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ConcurrentHashMap;

@Component
public class WebSocketHandlerServer implements WebSocketHandler {
    private static final Logger LOG = LoggerFactory.getLogger(WebSocketHandlerServer.class);
    private ConcurrentHashMap userMap = new ConcurrentHashMap();
//    private ConcurrentHashMap serviceMap = new ConcurrentHashMap();

    /**
     * 在WebSocket协商成功并且WebSocket连接打开并准备好使用后调用
     * @param webSocketSession
     * @throws Exception
     */
    @Override
    public void afterConnectionEstablished(WebSocketSession webSocketSession) throws Exception {
        LOG.info("WebSocket连接成功");
    }

    /**
     * 在新的WebSocket消息到达时调用
     * @param webSocketSession
     * @param webSocketMessage
     * @throws Exception
     */
    @Override
    public void handleMessage(WebSocketSession webSocketSession, WebSocketMessage<?> webSocketMessage) throws Exception {
        //如果消息没有任何内容，直接返回
        if(webSocketMessage.getPayloadLength()==0)return;
        final Date NOW = new Date();
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String msgStr = webSocketMessage.getPayload().toString();
        LOG.info("收到消息："+msgStr);
        SocketData socketData = JSONObject.parseObject(msgStr,SocketData.class);
        socketData.setSendTime(NOW);
        Integer msgType = socketData.getMsgType();
        Integer fromUserId = socketData.getFromUserId();
        if (msgType==0){        //心跳
            webSocketSession.sendMessage(new TextMessage("服务器的心跳回应-HeartBeat" + dateFormat.format(NOW)));
        } else if (msgType==1){ //注册
            //用户上线
            webSocketSession.getAttributes().put("socketData",socketData);
            userMap.put(fromUserId,webSocketSession);
            LOG.info("用户上线了....id：" + fromUserId);
            ServerHttpRequest serverHttpRequest = (ServerHttpRequest) webSocketSession.getAttributes().get("serverHttpRequest");
        } else if (msgType==2){ //文本信息
            sendMessgaeToUser(socketData);
        } else {
            sendMessgaeToUser(socketData);
        }
    }

    /**
     * 理底层WebSocket消息传输中的错误
     * @param webSocketSession
     * @param throwable
     * @throws Exception
     */
    @Override
    public void handleTransportError(WebSocketSession webSocketSession, Throwable throwable) throws Exception {
        LOG.info("处理底层WebSocket消息传输中的错误");
    }

    /**
     * 在任何一方关闭WebSocket连接之后或在发生传输错误之后调用
     * @param webSocketSession
     * @param closeStatus
     * @throws Exception
     */
    @Override
    public void afterConnectionClosed(WebSocketSession webSocketSession, CloseStatus closeStatus) throws Exception {
        LOG.info("WebSocket连接关闭");
    }

    /**
     * WebSocketHandler是否处理部分消息
     * @return
     */
    @Override
    public boolean supportsPartialMessages() {
        return false;
    }

    /**
     * 单发
     * @throws IOException
     */
    private void sendMessgaeToUser(SocketData socketData) throws IOException {
        WebSocketSession webSocketSession = (WebSocketSession) userMap.get(socketData.getToUserId());
        if(webSocketSession!=null && webSocketSession.isOpen()){
            //发送消息
            webSocketSession.sendMessage(new TextMessage(JSONObject.toJSONString(socketData)));
        }
    }

}
